package com.koron.standard.riskStock.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koron.standard.riskStock.bean.param.RiskMergeParam;
import com.koron.standard.riskStock.bean.po.RiskRef;
import com.koron.standard.riskStock.bean.po.RiskStock;
import com.koron.standard.riskStock.bean.query.RiskStockQuery;
import com.koron.standard.riskStock.bean.vo.RiskStockVo;
import com.koron.standard.riskStock.mapper.RiskStockMapper;
import com.koron.standard.utils.StandardCodeTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 风险库服务类
 *
 * @author jzp
 * @since 2021/9/1
 */
@Service
public class RiskStockService extends ServiceImpl<RiskStockMapper, RiskStock> {

    @Autowired
    private RiskRefService riskRefService;

    public RiskStock getById(String id) {
        return getBaseMapper().getRealById(id);
    }

    public QueryWrapper<RiskStock> queryWrapper(RiskStockQuery<RiskStockVo> pageQuery) {
        // 1. 分页查询风险库数据
        QueryWrapper<RiskStock> wrapper = new QueryWrapper<>();
        // 1.1 风险子类和风险父类查询
        wrapper.eq(StrUtil.isNotEmpty(pageQuery.getParentTypeName()), "parent_type_name", pageQuery.getParentTypeName());
        wrapper.eq(StrUtil.isNotEmpty(pageQuery.getTypeName()), "type_name", pageQuery.getTypeName());

        // 1.2 关键字查询
        if (StrUtil.isNotEmpty(pageQuery.getKeyword())) {
            wrapper.and(w -> w.like("keyword", pageQuery.getKeyword())
                    .or()
                    .like("others", pageQuery.getKeyword()));
        }

        wrapper.like(StrUtil.isNotEmpty(pageQuery.getOthers()), "others", pageQuery.getOthers());
        wrapper.eq(pageQuery.getStatus()!=null, "status", pageQuery.getStatus());
        wrapper.eq(StrUtil.isNotEmpty(pageQuery.getDeptId()), "dept_id", pageQuery.getDeptId());
        wrapper.like(StrUtil.isNotEmpty(pageQuery.getDeptName()), "dept_name", pageQuery.getDeptName());
        if (CollUtil.isNotEmpty(pageQuery.getDates())) {
            wrapper.between("cds.create_time", pageQuery.getDates().get(0), pageQuery.getDates().get(1));
        }

        wrapper.eq("delete_flag", 0);

        if (CollUtil.isNotEmpty(pageQuery.getRefTimes())) {
            wrapper.between("ref_time", pageQuery.getRefTimes().get(0), pageQuery.getRefTimes().get(1));
        }
        return wrapper;
    }


    public Page<RiskStockVo> page(RiskStockQuery<RiskStockVo> pageQuery) {
        Page<RiskStockVo> riskStockPage = pageQuery.convertPage();
        // 现在改为由前端进行排序
        // // 默认根据num进行降序排序
        // List<OrderItem> orders = riskStockPage.getOrders();
        // orders.add(0, new OrderItem("num", false));

        QueryWrapper<RiskStock> wrapper = queryWrapper(pageQuery);

        // 1.end 风险库分页查询结果
        getBaseMapper().selectPageVo(riskStockPage, wrapper);
        return riskStockPage;
    }

    public List<RiskStockVo> list(RiskStockQuery<RiskStockVo> pageQuery) {
        QueryWrapper<RiskStock> wrapper = queryWrapper(pageQuery);
        return getBaseMapper().selectPageVo(wrapper);
    }

    @Override
    public boolean saveOrUpdate(RiskStock riskStock) {
        // 1. 如果父类型的id为空且名称不为空则保存风险类型
        if (StrUtil.isEmpty(riskStock.getParentTypeName())) {
            riskStock.setParentTypeName("未分类");
        }
        if (StrUtil.isEmpty(riskStock.getTypeName())) {
            riskStock.setTypeName("无");
        }

        // 2. 设置code、status、num
        if (StrUtil.isEmpty(riskStock.getCode())) {
            riskStock.setCode(StandardCodeTools.getRiskStockCode());
        }
        if (riskStock.getStatus() == null) {
            // 默认启用
            riskStock.setStatus(1);
        }
        if (riskStock.getNum() == null) {
            riskStock.setNum(0);
        }

        // 3. 保存
        return super.saveOrUpdate(riskStock);
    }

    public boolean incrementRef(String id) {
        RiskStock riskStock = getById(id);
        RiskRef riskRef = new RiskRef();
        riskRef.setRiskId(id);
        riskRef.setRiskCode(riskStock.getCode());
        return riskRefService.save(riskRef);
    }

    /**
     * 将源id都合并到目标id中去
     */
    public void merge(RiskMergeParam riskMergeParam) {
        RiskStock targetRisk = getById(riskMergeParam.getTargetId());
        // 1. 修改源id的code为目标id的code
        LambdaUpdateWrapper<RiskStock> stockUpdateWrapper = new LambdaUpdateWrapper<RiskStock>();
        stockUpdateWrapper.set(RiskStock::getCode, targetRisk.getCode());
        stockUpdateWrapper.in(RiskStock::getId, riskMergeParam.getSourceIds());
        update(stockUpdateWrapper);

        // 2. 修改ref表中，源id的code为目标id的code
        LambdaUpdateWrapper<RiskRef> refUpdateWrapper = new LambdaUpdateWrapper<RiskRef>();
        refUpdateWrapper.set(RiskRef::getRiskCode, targetRisk.getCode());
        refUpdateWrapper.in(RiskRef::getRiskId, riskMergeParam.getSourceIds());
        riskRefService.update(refUpdateWrapper);

        // 3. 如果源数据有类似描述的数据，则拼接到目标数据中
        List<RiskStock> riskStocks = listByIds(riskMergeParam.getSourceIds());
        String other = riskStocks.stream().map(RiskStock::getOthers).collect(Collectors.joining(";"));
        if (StrUtil.isNotEmpty(other)) {
            LambdaUpdateWrapper<RiskStock> otherUpdateWrapper = new LambdaUpdateWrapper<RiskStock>();
            otherUpdateWrapper.set(RiskStock::getOthers, Objects.equals(targetRisk.getOthers(), null) ? "" : targetRisk.getOthers() + ";" + other);
            otherUpdateWrapper.eq(RiskStock::getId, riskMergeParam.getTargetId());
            update(otherUpdateWrapper);
        }

        // 4. 删除stock表中源id的数据
        removeByIds(riskMergeParam.getSourceIds());
    }

    public List<RiskStock> listByParent(String typeName) {
        LambdaQueryWrapper<RiskStock> wrapper = new LambdaQueryWrapper<>();
        // 如果typeName为空，则查询父类，如果不为空，则以typeName未父类来查询子类
        if (StrUtil.isEmpty(typeName)) {
            wrapper.groupBy(RiskStock::getParentTypeName);
        }else {
            wrapper.eq(RiskStock::getParentTypeName, typeName);
            wrapper.groupBy(RiskStock::getTypeName);
        }
        return list(wrapper);
    }

}
